package com.share.common.util;

import com.share.common.error.BizException;
import com.share.common.error.JsonReturnCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;

/**
 * 文件操作工具
 *
 * @author liw
 * @version 1.0
 * @date 2022/6/28 15:20
 */
@Slf4j
public class FileUtil {

    public static <T> Workbook list2Wb(List<T> list, Map<String, Function<T, String>> configMap, Workbook workbook, String sheetName) {

        Sheet sheet = workbook.createSheet(sheetName);
        Row row = sheet.createRow(0);
        int j = 0;
        for (Map.Entry<String, Function<T, String>> entry : configMap.entrySet()) {
            row.createCell(j++).setCellValue(entry.getKey());
        }
        int index = 1;
        for (T t : list) {
            j = 0;
            row = sheet.createRow(index++);
            for (Map.Entry<String, Function<T, String>> entry : configMap.entrySet()) {
                if (entry.getValue() != null) {
                    row.createCell(j++).setCellValue(entry.getValue().apply(t));
                }
            }
        }
        return workbook;
    }

    public static <T> Workbook list2Wb(List<T> list, Map<String, Function<T, String>> configMap) {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Sheet1");
        Row row = sheet.createRow(0);
        int j = 0;
        for (Map.Entry<String, Function<T, String>> entry : configMap.entrySet()) {
            row.createCell(j++).setCellValue(entry.getKey());
        }
        int index = 1;
        for (T t : list) {
            j = 0;
            row = sheet.createRow(index++);
            for (Map.Entry<String, Function<T, String>> entry : configMap.entrySet()) {
                if (entry.getValue() != null) {
                    row.createCell(j++).setCellValue(entry.getValue().apply(t));
                }
            }
        }
        return workbook;
    }

    /**
     * @return 新文件名
     */
    public static String createFilePath(String root) {
        String s = DateUtil.date2Str(LocalDateTime.now(), DateUtil.DATE_YMD);
        File f = new File(root + s);
        if (!f.exists()) {
            f.mkdirs();
        }
        return s + File.separator;
    }

    public static byte[] file2Bytes(File file) {
        byte[] imageBytes = null;
        try (FileInputStream fileInputStream = new FileInputStream(file)) {
            imageBytes = new byte[fileInputStream.available()];
            fileInputStream.read(imageBytes);
        } catch (IOException e) {
            e.printStackTrace();
            throw new BizException(JsonReturnCode.FILE_DOWNLOAD_ERROR);
        }
        return imageBytes;
    }

    public static void outWorkbook(HttpServletResponse response, Workbook workbook) {


        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=order_" + System.currentTimeMillis() + ".xlsx");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        // 创建缓冲输入流
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            workbook.write(response.getOutputStream());
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void outFile(HttpServletResponse response, File file) {
        String fileName = file.getName();
        if (!file.exists()) {
            throw new BizException(JsonReturnCode.FILE_DOWNLOAD_ERROR);
        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        // 创建缓冲输入流
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            outputStream.write(file2Bytes(file));
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static String imageToBase64(String imagePath) {
        try {
            File imageFile = new File(imagePath);
            InputStream fileInputStream = new FileInputStream(imageFile);
            byte[] imageBytes = new byte[(int) imageFile.length()];
            fileInputStream.read(imageBytes);
            fileInputStream.close();
            return Base64.getEncoder().encodeToString(imageBytes);
        } catch (IOException e) {
            e.printStackTrace();
            throw new BizException(JsonReturnCode.IMG_ERROR);
        }
    }

    /**
     * 获取某目录下所有的文件
     *
     * @param rootPath 根目录
     * @return 文件集合
     */
    public static List<File> getFileList(String rootPath) {
        try {
            List<File> fileList = new ArrayList<>();
            File file = new File(rootPath);
            addFileList(file, fileList);
            return fileList;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("目录不对啊。。。。");
        }
    }

    /**
     * 递归遍历目录
     *
     * @param file     目录
     * @param fileList 文件集合
     */
    private static void addFileList(File file, List<File> fileList) {
        if (file == null) {
            return;
        }
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (!CommonUtil.isEmpty(files)) {
                for (File fi : files) {
                    addFileList(fi, fileList);
                }
            }
        } else {
            fileList.add(file);
        }
    }

    public static String imageToUrlEncode(String imagePath) {
        try {
            return URLEncoder.encode(imageToBase64(imagePath), "UTF-8");
        } catch (Exception e) {
            throw new BizException(JsonReturnCode.IMG_ERROR);
        }
    }

    /**
     * 重新生成文件名
     *
     * @param originalFilename 原文件名
     * @return 新文件名
     */
    public static String makeFileName(String originalFilename) {
        String suffix = "";
        int beginIndex = originalFilename.lastIndexOf(".");
        if (beginIndex > 0) {
            suffix = originalFilename.substring(beginIndex);
        }
        return UUID.randomUUID().toString().replace("-", "") + suffix;
    }

    public static String makeNameByType(String type) {
        return UUID.randomUUID().toString().replace("-", "") + "." + type;
    }

    public static String getSuffix(String path) {
        int i = path.lastIndexOf(".");
        if (i >= 0) {
            return path.substring(i + 1);
        }
        throw new BizException(JsonReturnCode.FILE_NOT_EXIST_ERROR);
    }

}
